#pragma once

#include "cocos2d.h"
#include <thread>
#include <vector>
#include <functional>

USING_NS_CC;
using namespace std;

class EventHelper
{
	public:
	EventHelper(Node* targetNode = nullptr, bool regEvent = true);

	Node* thisNode;

	enum MouseEventType
	{
		MOUSEMOVE,
		MOUSEDOWN,
		MOUSEUP,
		MOUSESCROLL
	};

	enum MouseEventStatus
	{
		MOUSEOUTER,
		MOUSEENTER,
		MOUSEHOVER,
		MOUSELEAVE
	};

	enum MouseKey
	{
		MOUSELEFT,
		MOUSERIGHT,
		MOUSEMIDDLE,
		MOUSEKEY3,
		MOUSEKEY4,
		MOUSEKEY5,
		MOUSEKEY6,
		MOUSEKEY7,
		MOUSEKEY8,
		MOUSEKEY9
	};

	int orbit = 0;
	int mouseStatus = 0;
	bool isMouseKeyDown[10];
	int mouseKey = -1;
	unsigned int eventFlag = 0x0001;

	struct EventActions
	{
		function<void()> onMouseMove = nullptr;
		function<void()> onMouseDown = nullptr;
		function<void()> onMouseUp = nullptr;
		function<void()> onMouseScroll = nullptr;
	}additionalEventActions;

	void setEventFlagByBit(unsigned int flagbitpos);
	void setEventFlag(unsigned int flag);
	unsigned int moveEventFlagUp();
	unsigned int moveEventFlagDown();
	unsigned int getEventFlag();
	bool isEventFlagMatch();

	//Static functions

	static bool isMouseHoverNode(Node* node, Event* e, int angelZ = 0, float orbitOffsetX = 0, float orbitWidth = 0);
	static bool isMouseHoverArea(Vec2 position, Size size, Event* e);
	static bool isPointInNode(Node* node, Vec2 point);
	static bool isMouseKey(MouseKey key, Event* e);
	static Vec2 getMouseLoc(Event* e);
	static Vec2 getMouseLocInNode(Node* node, Event* e);

	static void addMouseListener(
		function<void(Event*)> onMove,
		function<void(Event*)> onDown,
		function<void(Event*)> onUp,
		function<void(Event*)> onScroll,
		Node* targetNode
	);

	void setAdditionalEventAction(MouseEventType mouseEventType, function<void()> func);
	void runAdditionalEventAction(MouseEventType mouseEventType);
	virtual void onMouseMove(Event* e) {};
	virtual void onMouseDown(Event* e) {};
	virtual void onMouseUp(Event* e) {};
	virtual void onMouseScroll(Event* e) {};
	void procMouseMove(Event* e);
	void procMouseDown(Event* e);
	void procMouseUp(Event* e);
};